<!-- 菜单详情弹窗 -->
<script lang="ts" setup>
import { ref, computed } from 'vue'
import DuiForm from '@/common-ui/dui-form/index.vue'
import type { IDbFormItem, IDbSelect } from '@/types/global'
import { ENUM_AUTH_TYPE, ENUM_YESORNO, ENUM_USEABLE } from '@/config/enum'
import useNotic from '@/hooks/useNotic'
import * as authApi from '@/api/auth'
import { MENU_FILE_MAP } from '@/config/menu'
import { BTN_AUTH_MAP } from '@/config/btn'
import { MENU_STATUS_LIST, MENU_TYPE_LIST } from '../config'
import type { IAuthInitData, IAuthData } from '../config/type'

const emits = defineEmits(['refresh'])

defineProps({
  // 标题
  title: {
    type: String,
    default: ''
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false
  }
})

// 详情id
const infoId = ref('')
// 父菜单类型
const ptype = ref<ENUM_AUTH_TYPE>(ENUM_AUTH_TYPE['目录'])
// 弹窗表单数据
const ruleFormRef = ref<InstanceType<typeof DuiForm>>()
// 表单配置
const formConfig = computed<IDbFormItem[]>(() => {
  return [
    { label: '上级', prop: 'pname', type: 'text', span: 24 },
    { label: '名称', prop: 'title', type: 'input', required: true, span: 12 },
    {
      label: '类型',
      prop: 'type',
      type: 'select',
      list: menuTypeList.value,
      required: true,
      span: 12,
      change: menuTypeChangeEvt
    },
    { label: '显示排序', prop: 'weigh', type: 'number', span: 12 },
    { label: '状态', prop: 'status', type: 'radio', list: MENU_STATUS_LIST, span: 12 },
    {
      label: '地址',
      prop: 'path',
      type: 'input',
      required: formData.value.type !== ENUM_AUTH_TYPE['按钮'],
      hide: formData.value.type == ENUM_AUTH_TYPE['按钮'],
      span: 24
    },
    {
      label: '权限字符',
      prop: 'apiUri',
      type: 'select',
      list: BTN_AUTH_MAP,
      span: 24,
      required: formData.value.type == ENUM_AUTH_TYPE['按钮'],
      hide: formData.value.type !== ENUM_AUTH_TYPE['按钮']
    },
    {
      label: '页面文件',
      prop: 'componentPath',
      type: 'select',
      list: MENU_FILE_MAP,
      span: 24,
      required: formData.value.type == ENUM_AUTH_TYPE['菜单'],
      hide: formData.value.type !== ENUM_AUTH_TYPE['菜单']
    },
    { label: '描述', prop: 'description', type: 'textarea', span: 24 },
    { prop: 'switch', type: 'slot', span: 24 }
  ]
})

// 表单默认数据
const defaultData: IAuthData = {
  pname: '',
  pid: '',
  title: '',
  type: '',
  apiUri: '',
  weigh: 0,
  status: ENUM_USEABLE['启用'],
  path: '',
  componentPath: '',
  description: '',
  hidden: ENUM_YESORNO['否'],
  tabHidden: ENUM_YESORNO['否'],
  hiddenLayout: ENUM_YESORNO['否'],
  keepAlive: ENUM_YESORNO['否']
}
// 表单数据
const formData = ref<IAuthData>(JSON.parse(JSON.stringify(defaultData)))
// 是否显示弹窗
const showDialog = ref(false)

/**
 * 菜单类型列表
 */
const menuTypeList = computed<IDbSelect[]>(() => {
  let typeList = MENU_TYPE_LIST
  switch (ptype.value) {
    case ENUM_AUTH_TYPE['目录']: // 目录下可以有目录、菜单、按钮
      typeList = MENU_TYPE_LIST
      break
    case ENUM_AUTH_TYPE['菜单']: // 菜单下可以有按钮
      typeList = MENU_TYPE_LIST.filter((item) => {
        return item.value == ENUM_AUTH_TYPE['按钮']
      })
      break
    case ENUM_AUTH_TYPE['按钮']: // 按钮不可添加子元素
      typeList = []
      break
    default:
  }
  return typeList
})
/**
 * 打开弹窗并初始化数据
 */
function init(params: IAuthInitData) {
  infoId.value = params.id ?? ''
  ptype.value = params.ptype ?? ENUM_AUTH_TYPE['目录']

  const defaultForm = JSON.parse(JSON.stringify(defaultData as any))
  Object.keys(defaultForm).forEach((key) => {
    ;(formData.value as any)[key] = params[key] ?? defaultForm[key]
  })

  menuTypeChangeEvt()
  showDialog.value = true
}

/**
 * 点击提交
 */
function submitClick() {
  ruleFormRef.value
    ?.validate()
    .then(() => {
      // 添加
      let reqFunc = authApi.addAuth
      let params: any = formData.value
      // 修改
      if (infoId.value) {
        reqFunc = authApi.editAuth
        params = { ...formData.value, id: infoId.value }
      }
      reqFunc(params).then((res) => {
        if (res.success) {
          useNotic().success('提交成功！')
          showDialog.value = false
          emits('refresh')
        }
      })
    })
    .catch(() => {})
}

/**
 * 菜单类型变化回调
 */
function menuTypeChangeEvt() {
  switch (formData.value.type) {
    case ENUM_AUTH_TYPE['目录']:
      formData.value.apiUri = ''
      formData.value.componentPath = ''
      formData.value.keepAlive = ENUM_YESORNO['否']
      formData.value.hidden = ENUM_YESORNO['否']
      formData.value.tabHidden = ENUM_YESORNO['否']
      formData.value.hiddenLayout = ENUM_YESORNO['否']
      break
    case ENUM_AUTH_TYPE['菜单']:
      formData.value.apiUri = ''
      break
    case ENUM_AUTH_TYPE['按钮']:
      formData.value.componentPath = ''
      formData.value.keepAlive = ENUM_YESORNO['否']
      formData.value.hidden = ENUM_YESORNO['否']
      formData.value.tabHidden = ENUM_YESORNO['否']
      formData.value.hiddenLayout = ENUM_YESORNO['否']
      break
    default:
  }
}

defineExpose({
  init
})
</script>

<template>
  <dui-dialog v-model="showDialog" :title="title">
    <dui-form ref="ruleFormRef" :form-config="formConfig" :form-data="formData" :disabled="disabled">
      <template #switchSlot>
        <div class="switch-box" v-if="([ENUM_AUTH_TYPE['目录'] , ENUM_AUTH_TYPE['菜单'] ] as string[]).includes(formData.type)">
          <div>是否隐藏菜单：</div>
          <el-switch :active-value="ENUM_YESORNO['是']" :inactive-value="ENUM_YESORNO['否']" v-model="formData.hidden" />
        </div>
        <div class="switch-box" v-if="formData.type == ENUM_AUTH_TYPE['菜单']">
          <div>是否隐藏标签：</div>
          <el-switch :active-value="ENUM_YESORNO['是']" :inactive-value="ENUM_YESORNO['否']" v-model="formData.tabHidden" />
        </div>
        <div class="switch-box" v-if="formData.type == ENUM_AUTH_TYPE['菜单']">
          <div>是否隐藏layout：</div>
          <el-switch :active-value="ENUM_YESORNO['是']" :inactive-value="ENUM_YESORNO['否']" v-model="formData.hiddenLayout" />
        </div>
        <div class="switch-box" v-if="formData.type == ENUM_AUTH_TYPE['菜单']">
          <div>是否缓存：</div>
          <el-switch :active-value="ENUM_YESORNO['是']" :inactive-value="ENUM_YESORNO['否']" v-model="formData.keepAlive" />
        </div>
      </template>
    </dui-form>
    <template #footer>
      <el-button @click="showDialog = false">关闭</el-button>
      <el-button type="primary" @click="submitClick" v-if="!disabled"> 确定 </el-button>
    </template>
  </dui-dialog>
</template>

<style lang="scss" scoped>
.switch-box {
  display: flex;
  align-items: center;
  margin-right: 30px;
}
</style>
